package main

import "fmt"

func main() {
	fmt.Println("9. 映射(Maps)")

	// 映射的创建
	fmt.Println("\n--- 映射的创建 ---")

	// 使用 make 创建映射
	var map1 map[string]int // nil映射
	fmt.Printf("nil映射 map1: %v, 长度: %d\n", map1, len(map1))

	map2 := make(map[string]int) // 空映射
	fmt.Printf("空映射 map2: %v, 长度: %d\n", map2, len(map2))

	// 字面量创建映射
	map3 := map[string]int{
		"apple":  5,
		"banana": 3,
		"orange": 8,
	}
	fmt.Printf("字面量创建 map3: %v, 长度: %d\n", map3, len(map3))

	// 创建时指定初始容量
	map4 := make(map[string]int, 10)
	fmt.Printf("指定容量 map4: %v, 长度: %d\n", map4, len(map4))

	// 映射的操作
	fmt.Println("\n--- 映射的操作 ---")

	// 添加键值对
	map2["one"] = 1
	map2["two"] = 2
	map2["three"] = 3
	fmt.Printf("添加元素后 map2: %v, 长度: %d\n", map2, len(map2))

	// 访问映射中的值
	value, exists := map3["apple"]
	if exists {
		fmt.Printf("map3[\"apple\"] = %d\n", value)
	} else {
		fmt.Println("键 'apple' 不存在")
	}

	// 访问不存在的键
	value, exists = map3["grape"]
	if exists {
		fmt.Printf("map3[\"grape\"] = %d\n", value)
	} else {
		fmt.Println("键 'grape' 不存在")
	}

	// 修改映射中的值
	map3["apple"] = 10
	fmt.Printf("修改后 map3[\"apple\"] = %d\n", map3["apple"])

	// 删除键值对
	delete(map3, "banana")
	fmt.Printf("删除 'banana' 后 map3: %v, 长度: %d\n", map3, len(map3))

	// 遍历映射
	fmt.Println("遍历 map3:")
	for key, value := range map3 {
		fmt.Printf("key: %s, value: %d\n", key, value)
	}

	// 只遍历键
	fmt.Println("只遍历键:")
	for key := range map3 {
		fmt.Printf("key: %s\n", key)
	}

	// 只遍历值
	fmt.Println("只遍历值:")
	for _, value := range map3 {
		fmt.Printf("value: %d\n", value)
	}

	// 映射的比较和复制
	fmt.Println("\n--- 映射的特性 ---")

	// 映射不能使用 == 进行比较（除了与nil比较）
	// map5 := map[string]int{"a": 1}
	// map6 := map[string]int{"a": 1}
	// fmt.Println(map5 == map6) // 编译错误

	// 映射是引用类型
	map7 := map3
	map7["orange"] = 999
	fmt.Printf("原映射 map3: %v\n", map3)
	fmt.Printf("引用映射 map7: %v\n", map7)

	// 不同类型的映射键
	fmt.Println("\n--- 不同类型的映射键 ---")

	// 整数键
	intMap := map[int]string{
		1: "one",
		2: "two",
		3: "three",
	}
	fmt.Printf("整数键映射: %v\n", intMap)

	// 多个字符串键
	multiKeyMap := map[[2]string]int{
		{"张", "三"}: 25,
		{"李", "四"}: 30,
	}
	fmt.Printf("复合键映射: %v\n", multiKeyMap)

	// 映射值为复杂类型
	type Person struct {
		Name string
		Age  int
	}
	personMap := map[string]Person{
		"zhangsan": {"张三", 25},
		"lisi":     {"李四", 30},
	}
	fmt.Printf("结构体值映射: %v\n", personMap)

	// 嵌套映射
	nestedMap := map[string]map[string]int{
		"fruits": {
			"apple":  5,
			"banana": 3,
		},
		"vegetables": {
			"carrot": 10,
			"tomato": 7,
		},
	}
	fmt.Printf("嵌套映射: %v\n", nestedMap)
	fmt.Printf("nestedMap[\"fruits\"][\"apple\"] = %d\n", nestedMap["fruits"]["apple"])

	// 检查映射是否为nil
	var nilMap map[string]int
	if nilMap == nil {
		fmt.Println("映射是nil")
	}

	// 映射的实际应用示例
	fmt.Println("\n--- 映射的实际应用 ---")

	// 统计字符出现次数
	text := "hello world"
	charCount := make(map[rune]int)
	for _, char := range text {
		charCount[char]++
	}
	fmt.Printf("字符统计: %v\n", charCount)

	// 使用映射作为缓存
	cache := make(map[string]interface{})
	cache["user_id"] = 12345
	cache["username"] = "张三"
	cache["is_admin"] = true
	fmt.Printf("缓存内容: %v\n", cache)
}
